package com.appspot.igo8poi.controller;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.appspot.igo8poi.model.bean.Poi;
import com.appspot.igo8poi.model.dao.PoiDao;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class AdminController extends BaseController {

	private static final Logger log = Logger.getLogger(AdminController.class.getName());

	@Autowired
	private PoiDao dao;

	@RequestMapping("/admin")
	public String admin() {
		return "admin";
	}

	private String IGO8_POI_TEMPLATE =
			"%line_number%|%group_name%|%poi_name%||%latitude%|%longitude%|_RUS||||||||||";

	private NumberFormat numberFormat = new DecimalFormat("000");

	private String getIgo8StringRepresentation(int lineNumber, Poi poi) {
		String poiName = numberFormat.format(poi.getNumber()) + " - " + poi.getName();

		return IGO8_POI_TEMPLATE
				.replaceAll("%line_number%", "" + lineNumber)
				.replaceAll("%group_name%", poi.getGroupName())
				.replaceAll("%poi_name%", poiName)
				.replaceAll("%latitude%", poi.getLatitude())
				.replaceAll("%longitude%", poi.getLongitude())
				;
	}

	@RequestMapping("/admin/export")
	public String exportData(HttpServletResponse response) {
		if (isUserAdmin()) {
			try {
//      		response.setBufferSize();
				response.setContentType("text/xml");
//        		response.setContentLength();
				ServletOutputStream outputStream = response.getOutputStream();

				List<Poi> pois = dao.getPois(getUserId());
				int lineNumber = 1;
				for (Poi poi : pois) {
					if (null != poi.getGroupName()) {
						outputStream.write((getIgo8StringRepresentation(lineNumber ,poi) + "\n").getBytes("UTF-8"));
						lineNumber++;
					}
				}
				outputStream.write("@My POI\n".getBytes("UTF-8"));

				outputStream.flush();
				outputStream.close();
			} catch (Exception e) {
				log.severe(exceptionDetails(e));
			}
		}
		return null;
	}

	@RequestMapping(value = "/admin/import", method = RequestMethod.POST)
	public String importData(HttpServletRequest request) {
		if (isUserAdmin()) {
			ServletFileUpload upload = new ServletFileUpload();
			try {
				FileItemIterator iter = upload.getItemIterator(request);
				while (iter.hasNext()) {
					FileItemStream item = iter.next();
					InputStream stream = item.openStream();
					String groupName = item.getName().replaceAll(".gpx", "");
					if (item.isFormField()) {
						// form fields
					} else {
						// files
						Collection<Poi> pois = new LinkedList<Poi>();
						String fileContent = convertStreamToString(stream);
						String[] poiStrings = fileContent.split("<rtept");
						int i = 0;
						for (String poiString : poiStrings) {
							Pattern lonPattern = Pattern.compile("lon=\".*?\"", Pattern.MULTILINE);
							Matcher mLon = lonPattern.matcher(poiString);
							Pattern latPattern = Pattern.compile("lat=\".*?\"", Pattern.MULTILINE);
							Matcher mLat = latPattern.matcher(poiString);
							Pattern namePattern = Pattern.compile("<name>.*?</name>", Pattern.MULTILINE);
							Matcher mName = namePattern.matcher(poiString);
							if (mLon.find() && mLat.find() && mName.find()) {
								i++;
								String latitude = mLat.group();
								latitude = latitude.substring(5, latitude.length() - 1);
								String longitude = mLon.group();
								longitude = longitude.substring(5, longitude.length() - 1);
								String name = mName.group();
								name = name.substring(6, name.length() - 7);
								Poi poi = new Poi(getUserId(), groupName, i, name, latitude, longitude);
								pois.add(poi);
							}
						}
						dao.savePois(pois);
					}
				}
			} catch (Exception e) {
				log.severe(exceptionDetails(e));
			}
		}
		return "admin";
	}

	private String convertStreamToString(InputStream is) throws IOException {
		if (is != null) {
			StringBuilder sb = new StringBuilder();
			String line;
			try {
				BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
				while ((line = reader.readLine()) != null) {
					sb.append(line).append("\n");
				}
			} finally {
				is.close();
			}
			return sb.toString();
		} else {
			return "";
		}
	}

	@RequestMapping("/")
	public String welcome() {
		return "user";
	}

}
